
var ConversionOptions = {
    //enums: String,  // enums as string names
    //longs: String,  // longs as strings (requires long.js)
    //bytes: String,  // bytes as base64 encoded strings
    //defaults: true, // includes default values
    //arrays: true,   // populates empty arrays (repeated fields) even if defaults=false
    //objects: true,  // populates empty objects (map fields) even if defaults=false
    //oneofs: true    // includes virtual oneof fields set to the present field's name
}

class ProtocolType<T> {
    public Name: string
    public Index: number
    public Proto: protobuf.Type
    private _msg: T

    public New(): T {
        return <T>{}
    }

    public ToObject(buffer: Uint8Array): T {
        let message = this.Proto.decode(buffer);
        //console.log(buffer)
        return <T>this.Proto.toObject(message, ConversionOptions)
    }

    public FromObject(payload: T): Uint8Array {
        let errMsg = this.Proto.verify(payload);
        if (errMsg)
            throw Error(errMsg);
        let message = this.Proto.create(payload)
        let buffer = this.Proto.encode(message).finish();
        //console.log(buffer)
        return buffer
    }

    public PackMessage(payload: T): egret.ByteArray {
        let buffer = this.FromObject(payload)
        let buf = new Uint8Array(buffer.length + 2)
        buf.set(buffer, 2)
        buf[0] = this.Index / 255
        buf[1] = this.Index % 255
        return new egret.ByteArray(buf)
    }

    public UnpackMessage(cmdBuf: egret.ByteArray): T {
        return this.ToObject(new Uint8Array(cmdBuf.buffer, 2, cmdBuf.buffer.byteLength - 2))
    }
}
